/*
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
*/

#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "culling_of_stratholme.h"
#include "Player.h"

enum Spells
{
	SPELL_CARRION_SWARM_N						= 52720,
	SPELL_CARRION_SWARM_H						= 58852,
	SPELL_MIND_BLAST_N							= 52722,
	SPELL_MIND_BLAST_H							= 58850,
	SPELL_SLEEP_N								= 52721,
	SPELL_SLEEP_H								= 58849,
	SPELL_VAMPIRIC_TOUCH						= 52723,
};

enum Events
{
	EVENT_SPELL_CARRION_SWARM					= 1,
	EVENT_SPELL_MIND_BLAST						= 2,
	EVENT_SPELL_SLEEP							= 3,
	EVENT_SPELL_VAMPIRIC_TOUCH					= 4,
};

enum Yells
{
    SAY_AGGRO                                   = 2,
    SAY_KILL                                    = 3,
    SAY_SLAY                                    = 4,
    SAY_SLEEP                                   = 5,
    SAY_30HEALTH                                = 6,
    SAY_15HEALTH                                = 7,
    SAY_ESCAPE_SPEECH_1                         = 8,
    SAY_ESCAPE_SPEECH_2                         = 9,
    SAY_OUTRO                                   = 10
};

class boss_mal_ganis : public CreatureScript
{
public:
    boss_mal_ganis() : CreatureScript("boss_mal_ganis") { }

    CreatureAI* GetAI(Creature* creature) const
    {
        return new boss_mal_ganisAI (creature);
    }

    struct boss_mal_ganisAI : public ScriptedAI
    {
        boss_mal_ganisAI(Creature* c) : ScriptedAI(c)
        {
			finished = false;
        }

        EventMap events;
		bool finished;

		void Reset() 
		{
			me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
			me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
			events.Reset();
			if (finished)
			{
				Talk(SAY_OUTRO);
				me->DespawnOrUnsummon(20000);
			}
		}

        void EnterCombat(Unit* /*who*/)
        {
            Talk(SAY_AGGRO);
			events.ScheduleEvent(EVENT_SPELL_CARRION_SWARM, 6000);
			events.ScheduleEvent(EVENT_SPELL_MIND_BLAST, 11000);
			events.ScheduleEvent(EVENT_SPELL_SLEEP, 20000);
			events.ScheduleEvent(EVENT_SPELL_VAMPIRIC_TOUCH, 15000);
        }

        void JustDied(Unit* /*killer*/)
        {
        }

        void KilledUnit(Unit* victim)
        {
            if (!urand(0,1))
                return;

            Talk(SAY_SLAY);
        }

		void DamageTaken(Unit* who, uint32 &damage, DamageEffectType, SpellSchoolMask)
		{
			if (!finished && damage >= me->GetHealth())
			{
				damage = 0;
				finished = true;
				me->SetRegeneratingHealth(false);
				me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
				me->SetReactState(REACT_PASSIVE);
				if (InstanceScript* pInstance = me->GetInstanceScript())
				{
					if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_ARTHAS)))
						cr->AI()->DoAction(ACTION_KILLED_MALGANIS);

					// give credit to players
					me->CastSpell(me, 58630, true);
				}

				// quest completion
				if (who)
					if (Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself())
						player->RewardPlayerAndGroupAtEvent(31006, player); // Royal Escort quest, Mal'ganis bunny

				EnterEvadeMode();
			}
		}

		void UpdateAI(uint32 diff)
        {
			if (!UpdateVictim())
				return;

			events.Update(diff);
			if (me->HasUnitState(UNIT_STATE_CASTING))
				return;

			switch (events.GetEvent())
			{
				case EVENT_SPELL_CARRION_SWARM:
					me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_CARRION_SWARM_N, SPELL_CARRION_SWARM_H), false);
					events.RepeatEvent(7000);
					break;
				case EVENT_SPELL_MIND_BLAST:
					if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
						me->CastSpell(target, DUNGEON_MODE(SPELL_MIND_BLAST_N, SPELL_MIND_BLAST_H), false);
					events.RepeatEvent(6000);
					break;
				case EVENT_SPELL_SLEEP:
					Talk(SAY_SLEEP);
					if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
						me->CastSpell(target, DUNGEON_MODE(SPELL_SLEEP_N, SPELL_SLEEP_H), false);
					events.RepeatEvent(17000);
					break;
				case EVENT_SPELL_VAMPIRIC_TOUCH:
					me->CastSpell(me, SPELL_VAMPIRIC_TOUCH, true);
					events.RepeatEvent(30000);
					break;
			}

			DoMeleeAttackIfReady();
        }
    };

};

void AddSC_boss_mal_ganis()
{
    new boss_mal_ganis();
}
